package fiado.dao.sqlserver;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import fiado.bean.Produto;
import fiado.exception.DaoException;
import fiado.util.DbUtilSqlServer;


public class ProdutoDAO {

	private static final String QUERY_SEQUENCE = "select isnull(max(ID_PRODUTO), 0) + 1 as NOVO_ID_PRODUTO from TB_PRODUTO";
	
	private static String LISTA_CAMPOS = 
			"	ID_PRODUTO, " +
			"	DS_PRODUTO, " +
			"	VL_PRODUTO, " +
			"	DT_CRIACAO ";
	
	private static final String QUERY_BUSCAR_TODOS = 
			"select " +
				ProdutoDAO.LISTA_CAMPOS +
			"from " +
			"	TB_PRODUTO " +
			"order by DS_PRODUTO ";
	
	private static final String QUERY_BUSCAR_POR_ID = 
			"select " +
				ProdutoDAO.LISTA_CAMPOS +
			"from " +
			"	TB_PRODUTO " +
			"where " +
			"	TB_PRODUTO.ID_PRODUTO = ? " +
			"order by DS_PRODUTO ";
	
	private static final String QUERY_APAGAR_POR_ID = "delete from TB_PRODUTO where TB_PRODUTO.ID_PRODUTO = ?";
	
	private static final String QUERY_CRIAR_PRODUTO = 
			"insert into TB_PRODUTO (" +
				ProdutoDAO.LISTA_CAMPOS +
			") " +
			"values(" +
			"	?, ?, ?, ?)" ;
	
	private static final String QUERY_ATUALIZAR_PRODUTO = 
			"update TB_PRODUTO " + 
			"set " + 
			"	DS_PRODUTO = ?, " +
			"	VL_PRODUTO = ?, " +
			"	DT_CRIACAO = ? " + 
			"where  " + 
			"   TB_PRODUTO.ID_PRODUTO = ? ";
	
	private static final String QUERY_BUSCAR_POR_DESCRICAO = 
			"select " +
				ProdutoDAO.LISTA_CAMPOS +
			"from " +
			"	TB_PRODUTO " +
			"where " +
			"	DS_PRODUTO like ? ";
	
	private int getProximoValorSequence() throws DaoException {
		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		int novoIdProduto = 0;
		try {
			
			statement = conn.prepareStatement(QUERY_SEQUENCE);
			result = statement.executeQuery();
			if (result.next()) {

				novoIdProduto = result.getInt("NOVO_ID_PRODUTO");
			}
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
		return novoIdProduto;
	}
	
	/**
	 * Este metodo retorna uma lista com todos os objetos Produto armazenados
	 * @return
	 * @throws DaoException 
	 */
	public List<Produto> buscarTodos() throws DaoException {
		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		List<Produto> listaTodos = new ArrayList<Produto>();
		try {
			
			statement = conn.prepareStatement(QUERY_BUSCAR_TODOS);
			result = statement.executeQuery();
			while (result.next()) {
				Produto produto = new Produto();
				produto.setId(result.getInt("ID_PRODUTO"));
				produto.setDescricao(result.getString("DS_PRODUTO"));
				produto.setValor(result.getDouble("VL_PRODUTO"));
				produto.setDataCriacao(DbUtilSqlServer.getJavaDate(result, "DT_CRIACAO"));
				listaTodos.add(produto);
			}
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
		return listaTodos;
	}

	/**
	 * Este metodo retorna uma lista com todos os objetos Produto armazenados
	 * que possuam <nome> no campo prenome ou no campo sobrenome
	 * @return
	 * @throws DaoException 
	 */
	public List<Produto> buscarPorDescricao(String descricao) throws DaoException {
		descricao = "%" + descricao + "%";
		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		List<Produto> listaTodos = new ArrayList<Produto>();
		try {
			
			statement = conn.prepareStatement(QUERY_BUSCAR_POR_DESCRICAO);
			statement.setString(1, descricao);
			result = statement.executeQuery();
			while (result.next()) {
				Produto produto = new Produto();
				produto.setId(result.getInt("ID_PRODUTO"));
				produto.setDescricao(result.getString("DS_PRODUTO"));
				produto.setValor(result.getDouble("VL_PRODUTO"));
				produto.setDataCriacao(DbUtilSqlServer.getJavaDate(result, "DT_CRIACAO"));
				listaTodos.add(produto);
			}
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
		return listaTodos;
	}
	
	/**
	 * Este metodo retorna o objeto Produto de acordo com o id
	 * @return
	 * @throws DaoException 
	 */
	public Produto buscarPorId(int idProduto) throws DaoException {
		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		Produto produto = null;
		try {
			
			statement = conn.prepareStatement(QUERY_BUSCAR_POR_ID);
			statement.setInt(1, idProduto);
			result = statement.executeQuery();
			if (result.next()) {
				produto = new Produto();
				produto.setId(result.getInt("ID_PRODUTO"));
				produto.setDescricao(result.getString("DS_PRODUTO"));
				produto.setValor(result.getDouble("VL_PRODUTO"));
				produto.setDataCriacao(DbUtilSqlServer.getJavaDate(result, "DT_CRIACAO"));
			}
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
		return produto;
	}
	
	/**
	 * Este metodo apaga o objeto Produto de acordo com o id
	 * @throws DaoException 
	 */
	public void apagar(int idProduto) throws DaoException {
		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		try {
			
			statement = conn.prepareStatement(QUERY_APAGAR_POR_ID);
			statement.setInt(1, idProduto);
			statement.execute();
			
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
	}	
	
	/**
	 * Este metodo apaga o objeto Produto
	 * @throws DaoException 
	 */
	public void apagar(Produto produto) throws DaoException {
		apagar(produto.getId());
	}
	
	/**
	 * Este metodo salva o objeto Produto 
	 * @throws DaoException 
	 */
	public void salvar(Produto produto) throws DaoException {
		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		try {
			statement = conn.prepareStatement(QUERY_ATUALIZAR_PRODUTO);
			
			statement.setString(1, produto.getDescricao());
			statement.setDouble(2, produto.getValor());
			statement.setDate(3, DbUtilSqlServer.getSqlDate(produto.getDataCriacao()));
			
			statement.setInt(4, produto.getId());

			statement.executeUpdate();
			
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
	}
	
	/**
	 * Este metodo cria o objeto Produto e retorna o objeto criado com o novo id
	 * preenchido
	 * @throws DaoException 
	 */
	public void criar(Produto produto) throws DaoException {
		int novoIdProduto = getProximoValorSequence();
		produto.setDataCriacao(new Date());

		Connection conn = DbUtilSqlServer.getConnection();
		PreparedStatement statement = null;
		ResultSet result = null;
		try {
									
			statement = conn.prepareStatement(QUERY_CRIAR_PRODUTO);
			statement.setInt(1, novoIdProduto);
			statement.setString(2, produto.getDescricao());
			statement.setDouble(3, produto.getValor());
			statement.setDate(4, DbUtilSqlServer.getSqlDate(produto.getDataCriacao()));

			statement.executeUpdate();
			
			produto.setId(novoIdProduto);
			
		} catch (SQLException e) {
			throw new DaoException(e);
		} finally {
			DbUtilSqlServer.close(conn, statement, result);
		}
	}
}
